package top.shenluw.springdemo.webflux;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.AbstractReferenceCountedByteBuf;
import io.netty.buffer.ByteBufUtil;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;

import javax.annotation.PostConstruct;

/**
 * @author Shenluw
 * 创建日期：2019/1/22 15:55
 */
@Configuration
public class NettyChatServerConfiguration {

    @Value("${netty.port}")
    private Integer port;

    public Integer getPort() {
        return port;
    }

    public void setPort(Integer port) {
        this.port = port;
    }

    public class DiscardServerHandler extends SimpleChannelInboundHandler<AbstractReferenceCountedByteBuf> {

        @Override
        protected void channelRead0(ChannelHandlerContext ctx, AbstractReferenceCountedByteBuf msg) throws Exception {
            System.out.println(msg.getClass());
            System.out.println("i am msg \n" + ByteBufUtil.prettyHexDump(msg.getBytes(0, new byte[1024])));
        }
    }

    @PostConstruct
    public void start() {
        System.out.println("start server at " + port);

        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();

        ServerBootstrap b = new ServerBootstrap();
        b.group(bossGroup, workerGroup)
                .channel(NioServerSocketChannel.class)
                .childHandler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    public void initChannel(SocketChannel ch) throws Exception {
                        ch.pipeline().addLast(new DiscardServerHandler());
                    }
                });
        b.childOption(ChannelOption.SO_KEEPALIVE, true);

        new Thread(() -> {
            try {
                ChannelFuture future;
                future = b.bind(port).sync();
                future.channel().closeFuture().sync();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                bossGroup.shutdownGracefully();
                workerGroup.shutdownGracefully();
            }
        }).start();

    }

}


